package edu.rpi.bt.client;

import java.util.Iterator;
import java.util.List;

import com.apress.progwt.client.college.ServiceCache;
import com.apress.progwt.client.domain.User;
import com.apress.progwt.client.domain.commands.SiteCommand;
import com.apress.progwt.client.rpc.EZCallback;
import com.apress.progwt.client.rpc.StdAsyncCallback;
import com.gwtext.client.core.EventObject;
import com.gwtext.client.core.Position;
import com.gwtext.client.core.RegionPosition;
import com.gwtext.client.data.ArrayReader;
import com.gwtext.client.data.FieldDef;
import com.gwtext.client.data.MemoryProxy;
import com.gwtext.client.data.RecordDef;
import com.gwtext.client.data.Store;
import com.gwtext.client.data.StringFieldDef;
import com.gwtext.client.util.JavaScriptObjectHelper;
import com.gwtext.client.widgets.Button;
import com.gwtext.client.widgets.MessageBox;
import com.gwtext.client.widgets.TabPanel;
import com.gwtext.client.widgets.Toolbar;
import com.gwtext.client.widgets.ToolbarButton;
import com.gwtext.client.widgets.Window;
import com.gwtext.client.widgets.event.ButtonListenerAdapter;
import com.gwtext.client.widgets.form.Field;
import com.gwtext.client.widgets.form.FormPanel;
import com.gwtext.client.widgets.form.TextArea;
import com.gwtext.client.widgets.form.TextField;
import com.gwtext.client.widgets.grid.ColumnConfig;
import com.gwtext.client.widgets.grid.ColumnModel;
import com.gwtext.client.widgets.grid.GridPanel;
import com.gwtext.client.widgets.grid.event.GridRowListener;
import com.gwtext.client.widgets.layout.AnchorLayoutData;
import com.gwtext.client.widgets.layout.BorderLayout;
import com.gwtext.client.widgets.layout.BorderLayoutData;
import com.gwtext.client.widgets.map.MapPanel;

import edu.rpi.bt.client.domain.Destination;
import edu.rpi.bt.client.domain.commands.SaveDestinationCommand;

public class ManageTripWindow extends Window{
    private Destination trip = new Destination();
    private String titleText = "Add A Trip";
    private String type = "add";
    private long tripId;
    private ManageTripWindow thisWindow = this;
    private BananaManager tripManager;
    
    private TabPanel tabPanel;
    private GridPanel grid = new GridPanel();
    final FormPanel formPanel = new FormPanel();  
    private Store store;
    
    private ServiceCache serviceCache;
    private User thisUser;

    private Boolean isReload = false;
    
    private List<Destination> locations;
    MapModule mm;
    public AddressStore addressStore = new AddressStore();
    
    ManageTripWindow( ServiceCache servCache){
        this.serviceCache = servCache;
  //      this.tripId=null;
        buildWindow();
        initUser( servCache);
    }
   
   ManageTripWindow( int row, Destination edittrip,  ServiceCache servCache ){
       long tripId = edittrip.getId();
       this.trip = edittrip;
       //MessageBox.alert("tripId " + tripId); 
       this.type = "edit";
       this.tripId = tripId;
       this.titleText = "Edit This Trip";
       this.serviceCache = servCache;
       buildWindow();
       initUser( servCache);
       initTrip( servCache, tripId);
   }
    
    private void buildWindow(){

        BorderLayoutData centerData = new BorderLayoutData(RegionPosition.CENTER);  
        centerData.setMargins(3, 0, 3, 3);  
        
        BorderLayoutData eastData = new BorderLayoutData(RegionPosition.EAST);  
        eastData.setMargins(3, 3, 0, 3);  

        mm = new MapModule(serviceCache, 500, 400);
        mm.addressStore = this.addressStore;
        
        MapPanel mapPanel = mm.mapPanel;
        tabPanel = buildTabPanel();
        
         this.setTitle(this.titleText);  
         this.setClosable(true);
         this.setDraggable(true);
         this.setWidth(750);  
         this.setHeight(450);  
         this.setPlain(true);  
         this.setModal(true);
         this.setLayout(new BorderLayout());  
         this.add( mapPanel, centerData);  
         this.add( tabPanel, eastData);  
         this.setCloseAction(Window.HIDE);  
    }

    private TabPanel buildTabPanel(){
        TabPanel tp = new TabPanel();
        tp.setWidth(240);
        
        FormPanel fp = buildFormPanel();
        fp.setTitle("Trip Properties");
        tp.add(fp);

        return tp;
    }
    
    private void addLocationTab(){
        GridPanel gp = getLocationGrid();
        gp.setTitle("Locations");
        tabPanel.add(gp);

    }
    
    private FormPanel buildFormPanel(){
        formPanel.setFrame(true);  
        formPanel.setWidth(240);
        formPanel.setHeight(400);
        formPanel.setLabelAlign(Position.TOP);
        
        TextField name = new TextField("Trip Name", "name");  
        name.setAllowBlank(false);  
        formPanel.add(name,  new AnchorLayoutData("95%"));  
        
        TextArea description = new TextArea("Description", "description");
        description.setHeight(100);
        formPanel.add(description,  new AnchorLayoutData("95%"));  
          Button viewAllButton = new Button("View Trip",new ButtonListenerAdapter(){
              public void onClick(Button button, EventObject e){
                  mm.renderAllMap(locations);
              }
          });
         //icon button  
         Button saveButton = new Button("Save", new ButtonListenerAdapter() {  
             public void onClick(Button button, EventObject e) {
              
                 Field[] fields = formPanel.getFields();
                 for( int i=0; i < fields.length; i++ ){
                     if( fields[i].getName() == "name"){
                         trip.setName( fields[i].getValueAsString() );
                     } else if( fields[i].getName() == "description"){
                         trip.setDescription( fields[i].getValueAsString() );
                     }
                 }
                 //MessageBox.alert("Name: " + trip.getName() + "<br>Descrip: " + trip.getDescription() );                 

                 //MessageBox.alert("user is " + thisUser.getNickname());
                 //ashoo: This is to how many destinations=trip set, to be commented
             //      MessageBox.alert("Num of destinations " + getDestinations().size());
           
                 
                 if( trip.getName() == null ){
                     MessageBox.alert("Error: You must enter a name for this trip.");
                     return;
                 }
            //     trip.setId(tripId);
                 trip.setUser(thisUser);
                 SaveDestinationCommand comm = new SaveDestinationCommand(
                         trip);
                 //MessageBox.alert("command");
                 serviceCache.executeCommand(comm,
                         new EZCallback<SiteCommand>() {
                     // MessageBox.alert("execute");
                     public void onSuccess( SiteCommand success) {

                         SaveDestinationCommand rtn = (SaveDestinationCommand) success;

                         trip.setId(rtn.getSavedDestinationID());
                         tripId = trip.getId();
                         //MessageBox.alert("Trip id " + trip.getId());
                         
                         if( thisWindow.type == "add"){
                             thisWindow.type = "edit";
                             thisWindow.titleText = "Edit This Trip";
                             thisWindow.initTrip(serviceCache, tripId);
                         }
                         
                         tripManager.reinitTripManager();
                     }

                 });
                                 

             }  
         });  
         // saveButton.setIconCls("search-icon");         
         formPanel.add(saveButton);  
         formPanel.add(viewAllButton);
        return formPanel;
    }
    
    private void setFormData(){
        Field[] fields = formPanel.getFields();
        
        for( int i=0; i < fields.length; i++ ){
            if( fields[i].getName() == "name"){
                fields[i].setValue( trip.getName() );
            } else if( fields[i].getName() == "description"){
                fields[i].setValue( trip.getDescription() );
            }
        }
    }
    
    private GridPanel getLocationGrid(){
        // Record definition
        RecordDef recordDef = new RecordDef(  
                new FieldDef[]{  
                        new StringFieldDef("locationname"),  
                }  
        );
        
        // Data Store
        Object[][] data = getLocationData();  
        MemoryProxy proxy = new MemoryProxy(data);  
        ArrayReader reader = new ArrayReader(recordDef);  
        store = new Store(proxy, reader);  
        store.load();
        
        // ColumnConfig
        ColumnConfig[] columns = new ColumnConfig[]{  
                new ColumnConfig("Location Name", "locationname", 230, true, null, "locationname"),  
        };  
        ColumnModel columnModel = new ColumnModel(columns);  

        
        // The tool bar
        Toolbar bottomToolbar = new Toolbar();  
        bottomToolbar.addFill();  
        bottomToolbar.addButton(new ToolbarButton("Add This Location", new ButtonListenerAdapter() {  
            public void onClick(Button button, EventObject e) {  
                ManageLocationWindow mlw = new ManageLocationWindow(trip, serviceCache);
                mlw.setTripWindow(thisWindow);
                mlw.addressStore = addressStore;
                mlw.show();
            }  
        }));  
        
        // Put it all together
        grid.setStore(store);  
        grid.setWidth(240); 
        grid.setColumnModel(columnModel);  
        grid.setFrame(false);  
        grid.setStripeRows(true);  

        grid.addGridRowListener(new GridRowListener() {  
            public void onRowClick(GridPanel grid, int rowIndex, EventObject e) {
                mm.updateMap(locations.get(rowIndex).getFullAddress(), JavaScriptObjectHelper.createObject(), mm);
                mm.setTextField(locations.get(rowIndex).getFullAddress());
            }  
  
            public void onRowDblClick(GridPanel grid, int rowIndex, EventObject e) {  
                ManageLocationWindow mlw = new ManageLocationWindow(trip, rowIndex, serviceCache);
                mlw.setTripWindow(thisWindow);
                mlw.addressStore = addressStore;
                mlw.show();
            }  
  
            public void onRowContextMenu(GridPanel grid, int rowIndex, EventObject e) {  
            }  
        });        
        

        grid.setBottomToolbar(bottomToolbar);  

        
        return grid;
    }
    
        private void initUser(ServiceCache servCache){
        //    this.serviceCache = servCache;
            
    
            serviceCache
            .getCurrentUser(new StdAsyncCallback<User>("Get User") {
    
                public void onSuccess(User result) {
                    super.onSuccess(result);
                    if (result == null) {
                     
                    } else {
                        load(result);
                        
                    }
                }
    
                public void onFailure(Throwable caught) {
                    super.onFailure(caught);
                  
                }
            });
        
    }
    private void initTrip(ServiceCache servCache, long tripId){
   //     serviceCache.getAllDestinations(new StdAsyncCallback<List<Destination>>("Get dests"){
        serviceCache.getAllLocations(tripId, new StdAsyncCallback<List<Destination>>("Get dests"){
            public void onSuccess(List<Destination> result) {
                super.onSuccess(result);
                if (result == null) {
                    MessageBox.alert("result for location null"); 
                } else {
                    //MessageBox.alert("load location result"); 
                    load(result);
                    
                    if(! isReload ){
                        setFormData();
                        addLocationTab();
                    } else {
                        updateDataStore();
                    }
                }
            }

            public void onFailure(Throwable caught) {
                super.onFailure(caught);
              
            }
        });
    }
    
        public void load(User user){
            this.thisUser=user;
      //      MessageBox.alert("user is " + user.getNickname());
     //       this.destinations=(List<Destination>) user.getDestinations();
            
        }
        public void load(List<Destination> dests){
           // MessageBox.alert("adding destination"); 
            this.locations=dests;
        }
        
        public  List<Destination> getDestinations(){
         //   System.out.println("inside getdests");
         //   MessageBox.alert("inside get destination..count " + locations.size()); 
            return this.locations;
        }
        
    
    private Object[][] getLocationData() {  
        Object[][] tmp = new Object[][]{};
        
        if( locations == null ){
            return tmp;
        }
        
        for (Iterator it = locations.iterator(); it.hasNext(); ) {
            Destination location = (Destination)it.next();
            tmp[tmp.length] = new Object[]{
                    location.getName(), location.getDescription()
            };
         }

        return tmp;
   }
    
    public void reinitTrip(){
        isReload = true;
        initTrip(serviceCache, tripId );
    }
    
    public void updateDataStore(){
        Object[][] data = getLocationData();  
        MemoryProxy proxy = new MemoryProxy(data);
        store.setDataProxy(proxy);
        store.reload();
    }
    
    public void setTripManager( BananaManager bm ){
        this.tripManager = bm;
    }    
}
